package com.zjcloud.jwgl.service.impl;

import java.math.BigDecimal;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zjcloud.common.utils.DateUtils;
import com.zjcloud.common.utils.SecurityUtils;
import com.zjcloud.jwgl.mapper.AcScheduleStatisticsMapper;
import com.zjcloud.jwgl.domain.AcScheduleStatistics;
import com.zjcloud.jwgl.service.IAcScheduleStatisticsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 排课结果统计Service业务层处理
 * 
 * @author zjcloud
 * @date 2024-12-19
 */
@Service
public class AcScheduleStatisticsServiceImpl implements IAcScheduleStatisticsService 
{
    private static final Logger log = LoggerFactory.getLogger(AcScheduleStatisticsServiceImpl.class);

    @Autowired
    private AcScheduleStatisticsMapper acScheduleStatisticsMapper;

    /**
     * 查询排课结果统计
     * 
     * @param statisticsId 排课结果统计主键
     * @return 排课结果统计
     */
    @Override
    public AcScheduleStatistics selectAcScheduleStatisticsById(Long statisticsId)
    {
        return acScheduleStatisticsMapper.selectAcScheduleStatisticsById(statisticsId);
    }

    /**
     * 查询排课结果统计列表
     * 
     * @param acScheduleStatistics 排课结果统计
     * @return 排课结果统计
     */
    @Override
    public List<AcScheduleStatistics> selectAcScheduleStatisticsList(AcScheduleStatistics acScheduleStatistics)
    {
        return acScheduleStatisticsMapper.selectAcScheduleStatisticsList(acScheduleStatistics);
    }

    /**
     * 新增排课结果统计
     * 
     * @param acScheduleStatistics 排课结果统计
     * @return 结果
     */
    @Override
    @Transactional
    public int insertAcScheduleStatistics(AcScheduleStatistics acScheduleStatistics)
    {
        acScheduleStatistics.setCreateTime(DateUtils.getNowDate());
        acScheduleStatistics.setCreateBy(SecurityUtils.getUsername());
        return acScheduleStatisticsMapper.insertAcScheduleStatistics(acScheduleStatistics);
    }

    /**
     * 修改排课结果统计
     * 
     * @param acScheduleStatistics 排课结果统计
     * @return 结果
     */
    @Override
    @Transactional
    public int updateAcScheduleStatistics(AcScheduleStatistics acScheduleStatistics)
    {
        acScheduleStatistics.setUpdateTime(DateUtils.getNowDate());
        acScheduleStatistics.setUpdateBy(SecurityUtils.getUsername());
        return acScheduleStatisticsMapper.updateAcScheduleStatistics(acScheduleStatistics);
    }

    /**
     * 批量删除排课结果统计
     * 
     * @param statisticsIds 需要删除的排课结果统计主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteAcScheduleStatisticsByIds(Long[] statisticsIds)
    {
        return acScheduleStatisticsMapper.deleteAcScheduleStatisticsByIds(statisticsIds);
    }

    /**
     * 删除排课结果统计信息
     * 
     * @param statisticsId 排课结果统计主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteAcScheduleStatisticsById(Long statisticsId)
    {
        return acScheduleStatisticsMapper.deleteAcScheduleStatisticsById(statisticsId);
    }

    /**
     * 根据任务ID查询统计信息
     * 
     * @param taskId 任务ID
     * @return 统计信息
     */
    @Override
    public AcScheduleStatistics selectStatisticsByTaskId(Long taskId)
    {
        return acScheduleStatisticsMapper.selectStatisticsByTaskId(taskId);
    }

    /**
     * 根据学期查询统计列表
     * 
     * @param semester 学期
     * @return 统计列表
     */
    @Override
    public List<AcScheduleStatistics> selectStatisticsBySemester(String semester)
    {
        return acScheduleStatisticsMapper.selectStatisticsBySemester(semester);
    }

    /**
     * 查询最近的统计记录
     * 
     * @param limit 限制数量
     * @return 统计列表
     */
    @Override
    public List<AcScheduleStatistics> selectRecentStatistics(Integer limit)
    {
        return acScheduleStatisticsMapper.selectRecentStatistics(limit);
    }

    /**
     * 根据任务ID删除统计信息
     * 
     * @param taskId 任务ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteStatisticsByTaskId(Long taskId)
    {
        return acScheduleStatisticsMapper.deleteStatisticsByTaskId(taskId);
    }

    /**
     * 批量根据任务ID删除统计信息
     * 
     * @param taskIds 任务ID数组
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteStatisticsByTaskIds(Long[] taskIds)
    {
        return acScheduleStatisticsMapper.deleteStatisticsByTaskIds(taskIds);
    }

    /**
     * 创建或更新统计信息
     * 
     * @param taskId 任务ID
     * @param semester 学期
     * @param totalCourses 总课程数
     * @param scheduledCourses 已排课程数
     * @param conflictCount 冲突数量
     * @return 结果
     */
    @Override
    @Transactional
    public boolean createOrUpdateStatistics(Long taskId, String semester, Integer totalCourses, 
                                          Integer scheduledCourses, Integer conflictCount)
    {
        try {
            // 检查是否已存在统计记录
            AcScheduleStatistics existingStats = acScheduleStatisticsMapper.selectStatisticsByTaskId(taskId);
            
            if (existingStats != null) {
                // 更新现有记录
                existingStats.setTotalCourses(totalCourses);
                existingStats.setScheduledCourses(scheduledCourses);
                existingStats.setConflictCount(conflictCount);
                
                // 计算各项指标
                calculateMetrics(existingStats);
                
                existingStats.setUpdateTime(DateUtils.getNowDate());
                existingStats.setUpdateBy(SecurityUtils.getUsername());
                
                int result = acScheduleStatisticsMapper.updateAcScheduleStatistics(existingStats);
                return result > 0;
            } else {
                // 创建新记录
                AcScheduleStatistics newStats = new AcScheduleStatistics();
                newStats.setTaskId(taskId);
                newStats.setSemester(semester);
                newStats.setTotalCourses(totalCourses);
                newStats.setScheduledCourses(scheduledCourses);
                newStats.setConflictCount(conflictCount);
                
                // 计算各项指标
                calculateMetrics(newStats);
                
                newStats.setCreateTime(DateUtils.getNowDate());
                newStats.setCreateBy(SecurityUtils.getUsername());
                
                int result = acScheduleStatisticsMapper.insertAcScheduleStatistics(newStats);
                return result > 0;
            }
        } catch (Exception e) {
            log.error("创建或更新统计信息失败，任务ID: {}, 错误: {}", taskId, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 更新算法执行统计
     * 
     * @param taskId 任务ID
     * @param iterationCount 迭代次数
     * @param executionTime 执行时间（毫秒）
     * @return 结果
     */
    @Override
    @Transactional
    public boolean updateAlgorithmStatistics(Long taskId, Integer iterationCount, Long executionTime)
    {
        try {
            AcScheduleStatistics stats = acScheduleStatisticsMapper.selectStatisticsByTaskId(taskId);
            if (stats != null) {
                stats.setGenerationCount(iterationCount);
                stats.setExecutionTime(executionTime);
                stats.setUpdateTime(DateUtils.getNowDate());
                stats.setUpdateBy(SecurityUtils.getUsername());
                
                int result = acScheduleStatisticsMapper.updateAcScheduleStatistics(stats);
                return result > 0;
            } else {
                log.warn("未找到任务统计信息，任务ID: {}", taskId);
                return false;
            }
        } catch (Exception e) {
            log.error("更新算法执行统计失败，任务ID: {}, 错误: {}", taskId, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 计算排课质量指标
     * 
     * @param statistics 统计对象
     */
    private void calculateMetrics(AcScheduleStatistics statistics)
    {
        try {
            Integer totalCourses = statistics.getTotalCourses();
            Integer scheduledCourses = statistics.getScheduledCourses();
            Integer conflictCount = statistics.getConflictCount();
            
            if (totalCourses == null) totalCourses = 0;
            if (scheduledCourses == null) scheduledCourses = 0;
            if (conflictCount == null) conflictCount = 0;
            
            // 计算教师满意度（基于冲突数量，冲突越少满意度越高）
            Double teacherSatisfaction = 1.0;
            if (scheduledCourses > 0) {
                teacherSatisfaction = Math.max(0.0, 1.0 - (conflictCount.doubleValue() / scheduledCourses.doubleValue()));
            }
            statistics.setTeacherSatisfaction(BigDecimal.valueOf(teacherSatisfaction));
            
            // 计算教室利用率（假设基于已排课程数量）
            Double classroomUtilization = 0.0;
            if (totalCourses > 0) {
                classroomUtilization = scheduledCourses.doubleValue() / totalCourses.doubleValue();
            }
            statistics.setClassroomUtilization(BigDecimal.valueOf(classroomUtilization));
            
            // 计算时间分布得分（假设均匀分布为最优）
            Double timeDistributionScore = Math.min(1.0, classroomUtilization * 1.2);
            statistics.setTimeDistributionScore(BigDecimal.valueOf(timeDistributionScore));
            
            // 计算总体评分（综合各项指标）
            Double overallScore = (teacherSatisfaction * 0.4 + classroomUtilization * 0.3 + timeDistributionScore * 0.3);
            statistics.setOverallScore(BigDecimal.valueOf(overallScore));
            
        } catch (Exception e) {
            log.error("计算排课质量指标失败: {}", e.getMessage(), e);
            // 设置默认值
            statistics.setTeacherSatisfaction(BigDecimal.valueOf(0.0));
            statistics.setClassroomUtilization(BigDecimal.valueOf(0.0));
            statistics.setTimeDistributionScore(BigDecimal.valueOf(0.0));
            statistics.setOverallScore(BigDecimal.valueOf(0.0));
        }
    }

    /**
     * 获取学期统计摘要
     * 
     * @param semester 学期
     * @return 统计摘要
     */
    @Override
    public AcScheduleStatistics getSemesterSummary(String semester)
    {
        try {
            List<AcScheduleStatistics> semesterStats = acScheduleStatisticsMapper.selectStatisticsBySemester(semester);
            
            if (semesterStats.isEmpty()) {
                return null;
            }
            
            // 计算汇总统计
            AcScheduleStatistics summary = new AcScheduleStatistics();
            summary.setSemester(semester);
            
            int totalCourses = 0;
            int totalScheduled = 0;
            int totalConflicts = 0;
            double totalTeacherSatisfaction = 0.0;
            double totalClassroomUtilization = 0.0;
            double totalTimeDistribution = 0.0;
            double totalOverallScore = 0.0;
            long totalExecutionTime = 0;
            int totalIterations = 0;
            
            for (AcScheduleStatistics stats : semesterStats) {
                totalCourses += (stats.getTotalCourses() != null ? stats.getTotalCourses() : 0);
                totalScheduled += (stats.getScheduledCourses() != null ? stats.getScheduledCourses() : 0);
                totalConflicts += (stats.getConflictCount() != null ? stats.getConflictCount() : 0);
                totalTeacherSatisfaction += (stats.getTeacherSatisfaction() != null ? stats.getTeacherSatisfaction().doubleValue() : 0.0);
                totalClassroomUtilization += (stats.getClassroomUtilization() != null ? stats.getClassroomUtilization().doubleValue() : 0.0);
                totalTimeDistribution += (stats.getTimeDistributionScore() != null ? stats.getTimeDistributionScore().doubleValue() : 0.0);
                totalOverallScore += (stats.getOverallScore() != null ? stats.getOverallScore().doubleValue() : 0.0);
                totalExecutionTime += (stats.getExecutionTime() != null ? stats.getExecutionTime() : 0);
                totalIterations += (stats.getGenerationCount() != null ? stats.getGenerationCount() : 0);
            }
            
            int count = semesterStats.size();
            summary.setTotalCourses(totalCourses);
            summary.setScheduledCourses(totalScheduled);
            summary.setConflictCount(totalConflicts);
            summary.setTeacherSatisfaction(BigDecimal.valueOf(totalTeacherSatisfaction / count));
            summary.setClassroomUtilization(BigDecimal.valueOf(totalClassroomUtilization / count));
            summary.setTimeDistributionScore(BigDecimal.valueOf(totalTimeDistribution / count));
            summary.setOverallScore(BigDecimal.valueOf(totalOverallScore / count));
            summary.setExecutionTime(totalExecutionTime);
            summary.setGenerationCount(totalIterations);
            
            return summary;
        } catch (Exception e) {
            log.error("获取学期统计摘要失败，学期: {}, 错误: {}", semester, e.getMessage(), e);
            return null;
        }
    }
}